import datetime
import hashlib
import random
import string
import uuid

from django.core.files.storage import default_storage
from django.db.models import Q
from django.shortcuts import render
from rest_framework import generics
from rest_framework.mixins import ListModelMixin
from rest_framework.response import Response
from rest_framework.views import APIView
from .models import *
from django.core.mail import send_mail

from .serializers import *
from .utils.jwt_author import create_token, JwtQueryParamsAuthentication


# Create your views here.

class TestAPIView(APIView):
    def get(self, request):
        return Response({"message": "Hello, world!"})


# 上传头像
class UploadAvatarAPIView(APIView):
    authentication_classes = []

    def post(self, request):
        file = request.FILES.get('file')  # 使用request.FILES获取上传文件
        if file:  # 检查文件是否存在
            # 生成随机文件名
            random_filename = str(uuid.uuid4())
            file_path = 'avatar/' + random_filename + '.jpg'
            print(file_path)

            # 使用Django的默认存储系统保存文件
            default_storage.save(file_path, file)

            # 返回响应
            return Response({'msg': '头像上传成功', 'imgurl': default_storage.url(file_path)})
        else:
            return Response({'msg': '头像上传失败'}, status=400)


# 发送邮件验证码
class SendEmailCaptchaAPIView(APIView):
    authentication_classes = []

    def get(self, request):
        email = request.GET.get('email')
        print("获取到的email是", email)
        if not email:
            return Response({'msg': '邮箱不能为空'}, status=403)

        # 生成验证码
        captcha = ''.join(random.sample(string.digits, 6))
        # 存储验证码到数据库
        CaptchaModel.objects.update_or_create(email=email, defaults={'captcha': captcha})  # 没有则新建
        try:
            send_mail('注册验证码', '您的验证码是：' + captcha, '', [email], fail_silently=False)
            return Response({'msg': '邮箱验证码发送成功'}, status=200)
        except Exception as e:
            print(e)
            return Response({'msg': '邮箱验证码发送失败'}, status=503)


# 注册用户
class RegisterAPIView(APIView):
    authentication_classes = []

    def post(self, request):
        email = request.data.get('email')
        captcha = request.data.get('captcha')
        print("获取到的email是", email)
        print("获取到的captcha是", captcha)
        if not CaptchaModel.objects.filter(email=email, captcha=captcha).exists():
            return Response({'msg': '验证码错误'}, status=403)
        nickname = request.data.get('nickname')
        password = request.data.get('password')
        intruduce = request.data.get('intruduce')
        avatar = request.data.get('avatar')
        # 校验数据
        if not all([email, captcha, nickname, password, intruduce, avatar]):
            return Response({'msg': '参数不能为空'}, status=403)
        # md5加密
        password = hashlib.md5(password.encode('utf-8')).hexdigest()
        if UserModel.objects.filter(email=email).exists():
            return Response({'msg': '邮箱已存在'}, status=403)
        try:
            user = UserModel.objects.create(email=email, nickname=nickname, password=password, introduce=intruduce,
                                            avatar=avatar)
            return Response({'msg': '注册成功'}, status=200)
        except Exception as e:
            print(e)
            return Response({'msg': '注册失败'}, status=403)


# 登录
class LoginAPIView(APIView):
    authentication_classes = []

    def post(self, request):
        email = request.data.get('email')
        password = request.data.get('password')
        if not all([email, password]):
            return Response({'msg': '邮箱密码不能为空'}, status=403)
        # md5加密
        password = hashlib.md5(password.encode('utf-8')).hexdigest()
        if not UserModel.objects.filter(email=email, password=password).exists():
            return Response({'msg': '邮箱或密码错误'}, status=403)
        user = UserModel.objects.get(email=email, password=password)
        token = create_token({'id': user.id})
        serializer = UserSerializer(user)
        data = serializer.data
        data['token'] = token
        data['avatar'] = data['avatar'].replace('/media/media', '/media')
        # print(data)
        return Response({'msg': '登录成功', 'userinfo': data}, status=200)


# 发布帖子
class PublishPostAPIView(APIView):
    def post(self, request):
        title = request.data.get('title')
        content = request.data.get('content')
        category = request.data.get('category')
        print(request.data)
        auth = JwtQueryParamsAuthentication()
        payload, token = auth.authenticate(request)
        if not payload:
            return Response({'msg': 'token错误'}, status=403)
        userid = payload.get('id')
        user = UserModel.objects.get(id=userid)
        if not user:
            return Response({'msg': '用户不存在'}, status=403)
        if not all([title, content, category]):
            return Response({'msg': '参数不能为空'}, status=403)
        try:
            post = PostModel.objects.create(title=title, content=content, category=category, user=user)
            return Response({'msg': '发布成功'}, status=200)
        except Exception as e:
            print(e)
            return Response({'msg': '发布失败'}, status=403)


# 获取帖子列表
class GetPostListAPIView(generics.ListAPIView):
    authentication_classes = []
    # 获取帖子列表
    queryset = PostModel.objects.all()
    serializer_class = PostSerializer
    serializer_class = PostSerializer

    def get_queryset(self):
        # 从请求中获取查询参数，例如：page, category等
        category_param = self.request.query_params.get('category', None)
        key_param = self.request.query_params.get('key', None)

        # 根据参数来过滤查询集
        queryset = PostModel.objects.all()
        if category_param:
            queryset = queryset.filter(category=category_param)
        if key_param:
            queryset = queryset.filter(Q(title__icontains=key_param) | Q(content__icontains=key_param))

        return queryset


# 获取帖子详情
class GetPostDetailAPIView(generics.RetrieveAPIView):
    authentication_classes = []
    queryset = PostModel.objects.all()
    serializer_class = PostSerializer
    lookup_field = 'id'

    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        instance.comment_count = CommentModel.objects.filter(post=instance).count()
        instance.like_count = LikeModel.objects.filter(post=instance).count()
        instance.favorite_count = FavoriteModel.objects.filter(post=instance).count()
        serializer = self.get_serializer(instance)
        data = serializer.data
        data['is_like'] = False
        data['is_favorite'] = False
        # 判断用户是否点赞
        token = request.headers.get('token')
        if token:
            payload, token = JwtQueryParamsAuthentication().authenticate(request)
            if payload:
                userid = payload.get('id')
                user = UserModel.objects.get(id=userid)
                if user:
                    data['is_like'] = LikeModel.objects.filter(user=user, post=instance).exists()
                    data['is_favorite'] = FavoriteModel.objects.filter(user=user, post=instance).exists()
        # 评论
        comments = CommentModel.objects.filter(post=instance)
        data['comments'] = CommentSerializer(comments, many=True).data
        return Response(data)


# 点赞
class LikeAPIView(APIView):
    def post(self, request):
        postid = request.data.get('postid')
        token = request.headers.get('token')
        if not token:
            return Response({'msg': 'token错误'}, status=403)
        payload, token = JwtQueryParamsAuthentication().authenticate(request)
        if not payload:
            return Response({'msg': 'token错误'}, status=403)
        userid = payload.get('id')
        user = UserModel.objects.get(id=userid)
        if not user:
            return Response({'msg': '用户不存在'}, status=403)
        if not LikeModel.objects.filter(user=user, post_id=postid).exists():
            LikeModel.objects.create(user=user, post_id=postid)
            post = PostModel.objects.get(id=postid)
            post.like_count += 1
            post.save()
            return Response({'msg': '点赞成功'}, status=200)
        else:
            LikeModel.objects.filter(user=user, post_id=postid).delete()
            post = PostModel.objects.get(id=postid)
            post.like_count -= 1
            post.save()
            return Response({'msg': '取消点赞成功'}, status=200)


# 收藏
class FavoriteAPIView(APIView):
    def post(self, request):
        postid = request.data.get('postid')
        token = request.headers.get('token')
        if not token:
            return Response({'msg': 'token错误'}, status=403)
        payload, token = JwtQueryParamsAuthentication().authenticate(request)
        if not payload:
            return Response({'msg': 'token错误'}, status=403)
        userid = payload.get('id')
        user = UserModel.objects.get(id=userid)
        if not FavoriteModel.objects.filter(user=user, post_id=postid).exists():
            FavoriteModel.objects.create(user=user, post_id=postid)
            post = PostModel.objects.get(id=postid)
            post.favorite_count += 1
            post.save()
            return Response({'msg': '收藏成功'}, status=200)
        else:
            FavoriteModel.objects.filter(user=user, post_id=postid).delete()
            post = PostModel.objects.get(id=postid)
            post.favorite_count -= 1
            post.save()
            return Response({'msg': '取消收藏成功'}, status=200)


# 添加评论
class CommentAPIView(APIView):
    def post(self, request):
        postid = request.data.get('postid')
        content = request.data.get('content')
        token = request.headers.get('token')
        if not token:
            return Response({'msg': 'token错误'}, status=403)
        payload, token = JwtQueryParamsAuthentication().authenticate(request)
        if not payload:
            return Response({'msg': 'token错误'}, status=403)
        userid = payload.get('id')
        user = UserModel.objects.get(id=userid)
        if not all([postid, content]):
            return Response({'msg': '参数不能为空'}, status=403)
        try:
            CommentModel.objects.create(user=user, post_id=postid, content=content)
            post = PostModel.objects.get(id=postid)
            post.comment_count += 1
            post.save()
            return Response({'msg': '评论成功'}, status=200)
        except Exception as e:
            print(e)
            return Response({'msg': '评论失败'}, status=403)


# 修改个人信息
class ChangeUserInfoAPIView(APIView):
    def post(self, request):
        nickname = request.data.get('nickname')
        avatar = request.data.get('avatar')
        introduce = request.data.get('introduce')

        token = request.headers.get('token')

        if not token:
            return Response({'msg': 'token错误'}, status=403)
        payload, token = JwtQueryParamsAuthentication().authenticate(request)
        if not payload:
            return Response({'msg': 'token错误'}, status=403)
        userid = payload.get('id')
        user = UserModel.objects.get(id=userid)
        if not all([nickname, avatar, introduce]):
            return Response({'msg': '参数不能为空'}, status=403)
        try:
            user.nickname = nickname
            user.avatar = avatar
            user.introduce = introduce
            user.save()
            serlizer = UserSerializer(user)
            data = serlizer.data
            data['avatar'] = data['avatar'].replace('/media/media/', '/media/')

            return Response({'msg': '修改成功', 'data': data}, status=200)
        except Exception as e:
            print(e)
            return Response({'msg': '修改失败'}, status=403)

    def get(self, request):
        token = request.headers.get('token')
        if not token:
            return Response({'msg': 'token错误'}, status=403)
        payload, token = JwtQueryParamsAuthentication().authenticate(request)
        if not payload:
            return Response({'msg': 'token错误'}, status=403)
        userid = payload.get('id')
        user = UserModel.objects.get(id=userid)
        data = {
            'nickname': user.nickname,
            'avatar': user.avatar.url,
            'introduce': user.introduce,
            'email': user.email,
        }
        data['avatar'] = data['avatar'].replace('/media/media/', '/media/')
        return Response(data)


# 用户主页
class UserHomeAPIView(APIView):
    def get(self, request):
        userid = request.query_params.get('id')
        print(request.query_params)
        print(userid)
        user = UserModel.objects.get(id=userid)
        if not user:
            return Response({'msg': '用户不存在'}, status=403)
        post = PostModel.objects.filter(user=user).order_by('-created_at')
        serializer = PostSerializer(post, many=True)
        data = serializer.data
        return Response(data)


class OtherUserAPIView(APIView):
    def get(self, request):
        userid = request.query_params.get('id')
        user = UserModel.objects.get(id=userid)
        if not user:
            return Response({'msg': '用户不存在'}, status=403)
        data = {
            'nickname': user.nickname,
            'avatar': user.avatar.url,
            'introduce': user.introduce,
            'email': user.email,
            'id': user.id
        }
        data['avatar'] = data['avatar'].replace('/media/media/', '/media/')
        return Response(data)


# 删除帖子
class DeletePostAPIView(APIView):
    def post(self, request):
        postid = request.data.get('postid')
        token = request.headers.get('token')
        if not token:
            return Response({'msg': 'token错误'}, status=403)
        payload, token = JwtQueryParamsAuthentication().authenticate(request)
        if not payload:
            return Response({'msg': 'token错误'}, status=403)
        userid = payload.get('id')
        print(userid)
        user = UserModel.objects.get(id=userid)
        if not PostModel.objects.filter(id=postid, user=user).exists():
            return Response({'msg': '帖子不存在'}, status=403)
        PostModel.objects.filter(id=postid, user=user).delete()
        return Response({'msg': '删除成功'}, status=200)


# 我的点赞
class MyLikeAPIView(APIView):
    def get(self, request):
        token = request.headers.get('token')
        if not token:
            return Response({'msg': 'token错误'}, status=403)
        payload, token = JwtQueryParamsAuthentication().authenticate(request)
        if not payload:
            return Response({'msg': 'token错误'}, status=403)
        userid = payload.get('id')
        user = UserModel.objects.get(id=userid)
        like = LikeModel.objects.filter(user=user)
        serializer = LikeSerializer(like, many=True)
        data = serializer.data
        return Response(data)


# 我的收藏
class MyFavAPIView(APIView):
    def get(self, request):
        token = request.headers.get('token')
        if not token:
            return Response({'msg': 'token错误'}, status=403)
        payload, token = JwtQueryParamsAuthentication().authenticate(request)
        if not payload:
            return Response({'msg': 'token错误'}, status=403)
        userid = payload.get('id')
        user = UserModel.objects.get(id=userid)
        fav = FavoriteModel.objects.filter(user=user)
        serializer = FavoriteSerializer(fav, many=True)
        data = serializer.data
        return Response(data)


# 修改帖子信息
class ChangePostAPIView(APIView):
    def post(self, request):
        postid = request.data.get('id')
        token = request.headers.get('token')
        if not token:
            return Response({'msg': 'token错误'}, status=403)
        payload, token = JwtQueryParamsAuthentication().authenticate(request)
        if not payload:
            return Response({'msg': 'token错误'}, status=403)
        userid = payload.get('id')
        user = UserModel.objects.get(id=userid)
        if not PostModel.objects.filter(id=postid, user=user).exists():
            return Response({'msg': '帖子不存在'}, status=403)
        # 校验数据是否为空
        if not all([request.data.get('title'), request.data.get('content')]):
            return Response({'msg': '参数不能为空'}, status=403)
        try:
            PostModel.objects.filter(id=postid, user=user).update(title=request.data.get('title'),
                                                                  content=request.data.get('content'),
                                                                  updated_at=datetime.datetime.now())
            return Response({'msg': '修改成功'}, status=200)
        except Exception as e:
            print(e)
            return Response({'msg': '修改失败'}, status=403)

    def get(self, request):
        postid = request.query_params.get('postid')
        token = request.headers.get('token')
        if not token:
            return Response({'msg': 'token错误'}, status=403)
        payload, token = JwtQueryParamsAuthentication().authenticate(request)
        if not payload:
            return Response({'msg': 'token错误'}, status=403)
        userid = payload.get('id')
        user = UserModel.objects.get(id=userid)
        if not user:
            return Response({'msg': '用户不存在'}, status=403)
        post = PostModel.objects.get(id=postid, user=user)
        serializer = PostSerializer(post)
        data = serializer.data
        return Response(data)


# 修改密码
class ChangePasswordAPIView(APIView):
    def post(self, request):
        payload, token = JwtQueryParamsAuthentication().authenticate(request)
        userid = payload.get('id')
        user = UserModel.objects.get(id=userid)
        if len(request.data.get('newpassword')) < 6:
            return Response({'msg': '密码长度不能小于6位'}, status=503)
        if not user:
            return Response({'msg': '用户不存在'}, status=403)
        oldmd5 = hashlib.md5(request.data.get('oldpassword').encode('utf-8')).hexdigest()
        if user.password != oldmd5:
            return Response({'msg': '旧密码错误'}, status=503)
        newmd5 = hashlib.md5(request.data.get('newpassword').encode('utf-8')).hexdigest()
        if newmd5 == oldmd5:
            return Response({'msg': '新密码不能与旧密码相同'}, status=503)
        user.password = newmd5
        user.save()
        return Response({'msg': '修改成功，请重新登录！'}, status=200)


# 注销用户
class LogoutAPIView(APIView):
    def get(self, request):
        payload, token = JwtQueryParamsAuthentication().authenticate(request)
        userid = payload.get('id')
        user = UserModel.objects.get(id=userid)
        if not user:
            return Response({'msg': '用户不存在'}, status=503)
        user.delete()
        return Response({'msg': '注销成功'}, status=200)